#pragma once

namespace My {

// AppBase

inline Doc & AppBase::GetDoc()
{
	//assert(m_pDoc != 0);
	//return * m_pDoc;
	return GetDocRef();
}

inline const Doc & AppBase::GetDoc() const
{
	//assert(m_pDoc != 0);
	//return * m_pDoc;
	return const_cast<AppBase &>(* this).GetDocRef();
}

inline Frame & AppBase::GetFrame()
{
	//assert(m_pFrame != 0);
	//return * m_pFrame;
	return GetFrameRef();
}

inline const Frame & AppBase::GetFrame() const
{
	//assert(m_pFrame != 0);
	//return * m_pFrame;
	return const_cast<AppBase &>(* this).GetFrameRef();
}

// App<D, F>

template <typename D, typename F>
App<D, F>::App()
	: m_pFrame(0)
{
}

template <typename D, typename F>
App<D, F>::~App()
{
}


template <typename D, typename F>
inline typename App<D, F>::DocType & App<D, F>::GetDoc()
{
	//return static_cast<DocType &>(AppBase::GetDoc());
	return * m_pDoc;
}

template <typename D, typename F>
inline const typename App<D, F>::DocType & App<D, F>::GetDoc() const
{
	//return static_cast<const DocType &>(AppBase::GetDoc());
	return * m_pDoc;
}

template <typename D, typename F>
inline typename App<D, F>::FrameType & App<D, F>::GetFrame()
{
	//return static_cast<FrameType &>(AppBase::GetFrame());
	return * m_pFrame;
}

template <typename D, typename F>
inline const typename App<D, F>::FrameType & App<D, F>::GetFrame() const
{
	//return static_cast<const FrameType &>(AppBase::GetFrame());
	return * m_pFrame;
}

template <typename D, typename F>
inline typename App<D, F>::ViewType & App<D, F>::GetView() 
{ 
	return GetFrame().GetView(); 
}

template <typename D, typename F>
inline typename App<D, F>::ViewType const & App<D, F>::GetView() const
{ 
	return GetFrame().GetView(); 
}

template <typename D, typename F>
inline Doc & App<D, F>::GetDocRef()		
{ 
	return * m_pDoc;
}

/*template <class T>
inline Doc * App<D, F>::CreateDoc()
{
	return new DocType;
}*/

template <typename D, typename F>
inline Frame & App<D, F>::GetFrameRef()		
{ 
	return * m_pFrame;
}

template <typename D, typename F>
BOOL App<D, F>::InitInstance()
{
	if (!AppBase::InitInstance())
		return FALSE;
	LoadStdProfileSettings(10);
	m_pDoc.reset(new DocType);

	m_pFrame.reset(new FrameType(* m_pDoc));
	if (!AppBase::LoadFrame(* m_pFrame, FrameType::ResourceID))
		return FALSE;
	m_pMainWnd = m_pFrame.get();
	m_pMainWnd->DragAcceptFiles(TRUE);

	m_pDoc->Init();

	return TRUE;
}

template <typename D, typename F>
int App<D, F>::ExitInstance()
{
	m_pFrame.reset();
	m_pDoc.reset();
	return AppBase::ExitInstance();
}

} // My
